home *** CD-ROM | disk | FTP | other *** search
- /*
- shutdown_library.c --- simple shutdown library
-
- This library is compatible with the shutdown library
- written by Olaf Barthel (AmiNet:util/boot/Shutdown2_0.lha).
- It is _NOT_ an update but a twin which is reduced to
- calling the hook functions. You can use the library of your
- preference. An update to the original library will be
- released later (see IDEAS, more ideas are welcome).
-
- This module is based on code from the original library
- Copyright © 1992 by Olaf `Olsen' Barthel (not for commercial use)
-
- Written by Bernhard Fastenrath (fasten@shw.com)
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/semaphores.h>
- #include <utility/hooks.h>
- #include <proto/exec.h>
- #include <string.h>
-
- #if defined (__GNUC__)
- #include <stabs.h>
- #endif
-
- #include "shutdownbase.h"
-
- typedef struct Hook Hook;
- typedef struct TagItem TagItem;
- typedef struct MinList MinList;
- typedef struct Node Node;
- typedef struct SignalSemaphore SignalSemaphore;
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase = NULL;
- struct Library *UtilityBase = NULL;
- struct Library *ShutdownBase;
-
- MinList ShutdownList;
- SignalSemaphore AccessLock;
- SignalSemaphore ShutdownLock;
- BYTE Closing = 0;
-
- #if defined (__GNUC__)
- const BYTE LibName[] = "shutdown.library";
- const BYTE LibIdString[] = "$VER: shutdown.library 2.3 (10-26-95)";
- const UWORD LibVersion = 2;
- const UWORD LibRevision = 3;
- #endif
-
- #if defined (__GNUC__)
- #define LIBRT
- #define REG(regname)
- #define STRUCT_MYLIB struct Library
- #elif defined (__SASC_60)
- #define LIBRT __saveds __asm
- #define REG(regname) register __ ## regname
- #define ADDTABL_1(name,arg1);
- #define ADDTABL_2(name,arg1,arg2);
- #define ADDTABL_3(name,arg1,arg2,arg3);
- #define ADDTABL_END();
- #define STRUCT_MYLIB struct MyLibrary
- #endif
-
- /*** internal functions ***/
-
- static void
- CallClientHooks (void)
- {
- if (ShutdownList.mlh_Head -> mln_Succ)
- {
- ShutdownInfo *Info, *NextInfo;
- ULONG Mode;
-
- Info = (ShutdownInfo *) ShutdownList.mlh_Head;
- while (NextInfo = (ShutdownInfo *) Info -> sdi_Node.mln_Succ)
- {
- Mode = SD_EXIT;
- CallHook (Info -> sdi_Hook, &Mode, NULL);
- Info = NextInfo;
- }
- }
- }
-
- static void
- cleanup (void)
- {
- if (DOSBase)
- CloseLibrary ((struct Library *) DOSBase);
- DOSBase = NULL;
- if (UtilityBase)
- CloseLibrary ((struct Library *) UtilityBase);
- UtilityBase = NULL;
- }
-
- /*** library interface ***/
-
- int LIBRT
- __UserLibInit (REG(a6) STRUCT_MYLIB *libbase)
- {
- SysBase = *(struct ExecBase **)4;
- ShutdownBase = (struct Library *) libbase;
-
- if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
- return 1;
- if (!(UtilityBase = OpenLibrary ("utility.library", 37)))
- {
- cleanup ();
- return 1;
- }
- InitSemaphore(&AccessLock);
- InitSemaphore(&ShutdownLock);
- NewList ((struct List *) &ShutdownList);
- return 0; /* success */
- }
-
- void LIBRT
- __UserLibCleanup (REG(a6) STRUCT_MYLIB *libbase)
- {
- cleanup ();
- }
-
- ADDTABL_1(LIBRexxDispatch,a0);
-
- LONG LIBRT
- LIBRexxDispatch (REG(a0) void *Message)
- {
- return 0;
- }
-
- ADDTABL_3(LIBAddShutdownInfoTagList,a0,a1,a2);
-
- APTR LIBRT
- LIBAddShutdownInfoTagList (REG(a0) Hook *Hook, REG(a1) STRPTR Name, REG(a2) TagItem *TagList)
- {
- if (!Closing)
- {
- if (Hook && Name && TagList)
- {
- ShutdownInfo *Info;
- LONG Len = strlen (Name);
-
- if (Info = (ShutdownInfo *) AllocVec (sizeof (ShutdownInfo) + Len + 1, MEMF_PUBLIC | MEMF_CLEAR))
- {
- ObtainSemaphore (&AccessLock);
- Info -> sdi_Hook = Hook;
- Info -> sdi_Name = (STRPTR)(Info + 1);
- strcpy (Info -> sdi_Name, Name);
- AddTail ((struct List *) &ShutdownList, (struct Node *) Info);
- ReleaseSemaphore (&AccessLock);
- return Info;
- }
- }
- }
- return NULL;
- }
-
- ADDTABL_1(LIBRemShutdownInfo,a0);
-
- LONG LIBRT
- LIBRemShutdownInfo (REG(a0) ShutdownInfo *Info)
- {
- if (!Closing && Info)
- {
- ShutdownInfo *node, *next;
-
- ObtainSemaphore (&AccessLock);
- node = (ShutdownInfo *) ShutdownList.mlh_Head;
- while (next = (ShutdownInfo *) node -> sdi_Node.mln_Succ)
- {
- if (Info == (ShutdownInfo *) node)
- {
- Remove ((struct Node *) Info);
- FreeVec (Info);
- ReleaseSemaphore (&AccessLock);
- return TRUE;
- }
- node = next;
- }
- ReleaseSemaphore (&AccessLock);
- }
- return FALSE;
- }
-
- ADDTABL_1(LIBShutdown,d0);
-
- LONG LIBRT
- LIBShutdown (REG(d0) ULONG mode)
- {
- if (!AttemptSemaphore (&ShutdownLock))
- return FALSE;
- else
- {
- /* mode is ignored by this library but
- not by the original shutdown.libray */
-
- CallClientHooks ();
- ReleaseSemaphore (&ShutdownLock);
- return TRUE;
- }
- return FALSE;
- }
-
- ADDTABL_END();
-